package etcd

import (
	"context"
	"fmt"
	"gitee.com/justin0218/store"
	"github.com/coreos/etcd/clientv3"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type Service struct {
	client    *clientv3.Client
	RegistKey string
	LeaseID   clientv3.LeaseID
	Conf      store.Config
	Log       store.Log
}

func Register() {
	return
	svr, err := NewService()
	if err != nil {
		panic(err)
	}
	err = svr.RegService()
	if err != nil {
		panic(err)
	}
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGQUIT)
	go func() {
		sig := <-ch
		err = svr.UnRegService() //把服务的key绑定到租约下面
		if i, ok := sig.(syscall.Signal); ok {
			os.Exit(int(i))
		} else {
			os.Exit(0)
		}
	}()
}

// 指定client端，Endpoints是etcd server的机器列表，DialTimeout是计算节点链接服务的超时时间
func NewService() (*Service, error) {
	config := clientv3.Config{
		Endpoints:   []string{":2379"},
		DialTimeout: 10 * time.Second,
	}
	client, err := clientv3.New(config)
	if err != nil {
		return nil, err
	}
	return &Service{client: client}, nil
}

var retryNum = 10

//注册服务
func (s *Service) RegService() error {
	retryNum--
	kv := clientv3.NewKV(s.client)
	s.RegistKey = fmt.Sprintf("/%s/%s/%s", s.Conf.Get().Etcd.Schema, s.Conf.Get().Etcd.Name, s.Conf.Get().Etcd.Key)
	ctx := context.Background()
	lease := clientv3.NewLease(s.client)
	//设置租约过期时间为20秒
	leaseRes, err := lease.Grant(ctx, 20)
	if err != nil {
		return err
	}
	s.LeaseID = leaseRes.ID
	_, err = kv.Put(context.Background(), s.RegistKey, s.Conf.Get().Etcd.Key, clientv3.WithLease(leaseRes.ID)) //把服务的key绑定到租约下面
	if err != nil {
		return err
	}
	keepaliveRes, err := lease.KeepAlive(context.Background(), leaseRes.ID)
	if err != nil {
		s.Log.Get().Error("lease KeepAliveOnce err:%v", err)
		return err
	}
	go lisKeepAlive(keepaliveRes)
	return err
}

//注册服务
func (this *Service) UnRegService() error {
	kv := clientv3.NewKV(this.client)
	ctx := context.Background()
	_, err := kv.Delete(ctx, this.RegistKey) //把服务的key绑定到租约下面
	if err != nil {
		return err
	}
	return err
}

func lisKeepAlive(keepaliveRes <-chan *clientv3.LeaseKeepAliveResponse) {
	for {
		select {
		case ret := <-keepaliveRes:
			if ret != nil {
				//fmt.Println("续租成功", time.Now(), ret.String())
			}
		}
	}
}
